/******************************************************************************
 * (C) Copyright 2012 Atech-Automotive
 * FILE NAME:    SCI.c
 * DESCRIPTION:
 * 
 * DATE BEGUN:   2020/09/07
 * BY:           yong.ding
 * PRODUCT NAME:
 * APPLICATION:
 * TARGET H/W:
 * DOC REF:
 *****************************************************************************
 */

/*****************************************************************************
** #include 

*****************************************************************************/
#include "system.h"
#include "sys_micro.h"
#include "drv_SCI.h"

/*****************************************************************************
** #define
*****************************************************************************/    



/*****************************************************************************
** typedef
*****************************************************************************/
typedef struct
{
    UINT8   u8_count;
    UINT8   u8_head;
    UINT8   u8_buffer[SCI_BUFFER_SIZE];
}SCI_DATA_BUFFER_S;



static SCI_DATA_BUFFER_S s_SCI1TxDataBuffer;
static SCI_DATA_BUFFER_S s_SCI1RxDataBuffer;

//static DEGUG_MODE_E e_debugMode = DEBUG_STOP_MODE;//DEBUG_WAVE_MODE;
/*****************************************************************************
** global variable
*****************************************************************************/
SCI_STATE_E sci1_state = SCI_SUCCESS;


/*****************************************************************************
** static variables
*****************************************************************************/

/*****************************************************************************
** static constants
*****************************************************************************/


/*****************************************************************************
** static function prototypes
*****************************************************************************/
static void sciDataBuffer_pop(UINT8* p_u8_data, SCI_DATA_BUFFER_S* p_s_buffer);//, BOOL b_dataProtect);
static void sciDataBuffer_push(UINT8 u8_data, SCI_DATA_BUFFER_S* p_s_buffer);//, BOOL b_dataProtect);
static void drv_SCI1_DataBuffer_init(void);

//static void sciFrameBuffer_pop(UINT8* p_u8_data, SCI_RXFRAME_BUFFER_S* p_s_buffer);//, BOOL b_dataProtect);
//static void sciFrameBuffer_push(UINT8 u8_data, SCI_RXFRAME_BUFFER_S* p_s_buffer);//, BOOL b_dataProtect);


/*****************************************************************************
** function prototypes
*****************************************************************************/
/*
    ((UINT8)13)//115200
*/
#define SCI1_BAUD   ((UINT8)9)//115200
//#define SCI1_BAUD   ((UINT8)104)//9600  104 = 0X68
/****************************************************************************/
void drv_sciInit(void)
{ 
    /* 8 data, no parity, 1 stop */
    SCI1CR1 = 0x00;
    SCI1CR2 = 0x00;
    SCI1SR2 = 0x00;    
    SCI1DRL = 0x00; 
    
    /* clear status flags */
    (void)SCI1SR1; 
    (void)SCI1DRL;    
    
    /* baudrate */
    SCI1BD = SCI1_BAUD;  
        
    /* SCI disabled in wait mode */
    SCI1CR1_SCISWAI = 1;          
    
    /* transmitter enable and receiver enable */
    SCI1CR2 |= (SCI1CR2_TE_MASK | SCI1CR2_RE_MASK | SCI1CR2_RIE_MASK);
	drv_SCI1_DataBuffer_init();
}

static BOOL drv_sci1SendChar(UINT8 u8_data)
{
    if(SCI1SR1_TDRE)/*Transmit data register is empty*/
    {
        SCI1DRL = u8_data;
        return TRUE;
    }
    
    return FALSE;
}

void drv_sci1SendHandler(void)
{   
    static UINT8 u8_txData;
    static BOOL b_txComplete = TRUE;
    static UINT8 u8_txDataTemp = 0;
    
    if(b_txComplete)
    {
        if(s_SCI1TxDataBuffer.u8_count > 0)
        {
            sciDataBuffer_pop(&u8_txData, &s_SCI1TxDataBuffer); 
            if(drv_sci1SendChar(u8_txData))
            {
                b_txComplete = TRUE;
            }
            else
            {
                b_txComplete = FALSE;
            }
        }          
    }    
    else
    {
        if(drv_sci1SendChar(u8_txData))
        {
            b_txComplete = TRUE;
        }
    }    
}



BOOL drv_sci1SendFrame(UINT8 id,BOOL sub_exist,UINT8 sub_id,UINT8 txData_len,UINT8* p_u8_txData)
{
	UINT8 i=0;
	UINT8 check_sum=0;
	UINT8 len=0;

	if(sub_exist == FALSE)
	{
		if((drv_sci1_u8_getRxMessageCount()+txData_len+6) > SCI_BUFFER_SIZE)
		{
			sci1_state = SCI_TX_BUFFER_FULL;
			return FALSE;
		}
	    sciDataBuffer_push(0xAA,    &s_SCI1TxDataBuffer);
	    sciDataBuffer_push(0x75,    &s_SCI1TxDataBuffer);
	    sciDataBuffer_push(id,    &s_SCI1TxDataBuffer);					//ming ling zi
		sciDataBuffer_push(txData_len,	&s_SCI1TxDataBuffer);//shu ju kuai chang du
		check_sum = 0xAA + 0x75 + id + txData_len;
		for(i=0;i<txData_len;i++)								//shu ju kuai
		{
			sciDataBuffer_push(*(p_u8_txData+i),	&s_SCI1TxDataBuffer);
			check_sum += *(p_u8_txData+i);
		}
		sciDataBuffer_push(check_sum,    &s_SCI1TxDataBuffer);//check sum
		sciDataBuffer_push(0xD5,    &s_SCI1TxDataBuffer);
	}
	else
	{
		if((drv_sci1_u8_getRxMessageCount()+txData_len+8) > SCI_BUFFER_SIZE)
		{
			sci1_state = SCI_TX_BUFFER_FULL;
			return FALSE;
		}
	    sciDataBuffer_push(0xAA,    &s_SCI1TxDataBuffer);
	    sciDataBuffer_push(0x75,    &s_SCI1TxDataBuffer);
	    sciDataBuffer_push(id,    &s_SCI1TxDataBuffer);					//ming ling zi
		len = txData_len + 2;
		sciDataBuffer_push(len,	&s_SCI1TxDataBuffer);//chang du
		sciDataBuffer_push(sub_id,	&s_SCI1TxDataBuffer);//zi ming ling zi
		sciDataBuffer_push(txData_len,	&s_SCI1TxDataBuffer);//shu ju kuai chang du
		check_sum = 0xAA + 0x75 + id + len + sub_id + txData_len;
		for(i=0;i<txData_len;i++)								//shu ju kuai
		{
			sciDataBuffer_push(*(p_u8_txData+i),	&s_SCI1TxDataBuffer);
			check_sum += *(p_u8_txData+i);
		}
		sciDataBuffer_push(check_sum,    &s_SCI1TxDataBuffer);//check sum
		sciDataBuffer_push(0xD5,    &s_SCI1TxDataBuffer);

	}
	return TRUE;
}


/*data deal*/
static void sciDataBuffer_pop(UINT8* p_u8_data, SCI_DATA_BUFFER_S* p_s_buffer)//, BOOL b_dataProtect)
{
    if(p_s_buffer->u8_count != 0)
    {
        *p_u8_data = p_s_buffer->u8_buffer[p_s_buffer->u8_head];
                                                              /* % SCI_TX_BUFFER_SIZE, it's optimizatiion for %*/
        p_s_buffer->u8_head = (UINT8)((p_s_buffer->u8_head + 1U) % SCI_BUFFER_SIZE);
        p_s_buffer->u8_count--;
        
    }
}


static void sciDataBuffer_push(UINT8 u8_data, SCI_DATA_BUFFER_S* p_s_buffer)//, BOOL b_dataProtect)
{
    UINT8 u8_tail;
    if(p_s_buffer->u8_count <= SCI_BUFFER_SIZE)
    {                                                               /* % SCI_TX_BUFFER_SIZE, it's optimizatiion for %*/
        u8_tail = (UINT8)((p_s_buffer->u8_head + p_s_buffer->u8_count) % SCI_BUFFER_SIZE);
        p_s_buffer->u8_buffer[u8_tail]= u8_data;
        p_s_buffer->u8_count++;
    }
}

void drv_sci1DataBuffer_push(UINT8 u8_data)
{
    sciDataBuffer_push(u8_data, &s_SCI1RxDataBuffer); 
}



static void drv_SCI1_DataBuffer_init(void)
{
	s_SCI1TxDataBuffer.u8_head = 0;
	s_SCI1TxDataBuffer.u8_count = 0;
	s_SCI1RxDataBuffer.u8_head = 0;
	s_SCI1RxDataBuffer.u8_count = 0;
}
// shi fou
UINT8 drv_sci1DataRxBuffer_full(void)//rx buff shi fou full
{
	if(s_SCI1RxDataBuffer.u8_count >= SCI_BUFFER_SIZE)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

UINT8 drv_sci1DataTxBuffer_full(void)//Tx buff shi fou full
{
	if(s_SCI1TxDataBuffer.u8_count >= SCI_BUFFER_SIZE)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

UINT8 drv_sci1_u8_getRxMessageCount(void)
{
	return s_SCI1RxDataBuffer.u8_count;
}

BOOL drv_sci1_v_getMessage(UINT8 *u8_id,UINT8 *u8_sub_id,UINT8 *u8_length,UINT8 *p_u8_txData)
{
	static UINT8 Temp_get = 0;	
	static UINT8 Temp_get_last = 0;
	static BOOL Receive_frame_permission_flag = 0;
	static UINT8 temp_RxOneFrameBuffer[30];
	static UINT8 temp_RxOneFrame_BytesCn = 0;
	UINT8 check_sum=0;
	UINT8 i;
	while(drv_sci1_u8_getRxMessageCount() > 0)
	{
		sciDataBuffer_pop(&Temp_get, &s_SCI1RxDataBuffer); 
		if(Temp_get_last == 0xAA && (Temp_get == 0X75))
		{
			temp_RxOneFrame_BytesCn = 0;
			temp_RxOneFrameBuffer[temp_RxOneFrame_BytesCn] = 0xAA;
			temp_RxOneFrame_BytesCn++;
			Receive_frame_permission_flag = 1;
		}
		if(Receive_frame_permission_flag)
		{
			temp_RxOneFrameBuffer[temp_RxOneFrame_BytesCn] = Temp_get;
			temp_RxOneFrame_BytesCn++;
		}
		if(Receive_frame_permission_flag == TRUE && (Temp_get == 0xD5))
	  	{
			Receive_frame_permission_flag = FALSE;
			//fen xi s_SCI1RxDataBuffer bing qie  cun fang dao xiang ying wei zhi zhong。
			if(temp_RxOneFrame_BytesCn >= 8)
			{
				for(i=0;i<temp_RxOneFrame_BytesCn-2;i++)
				{
					check_sum += temp_RxOneFrameBuffer[i];
				}
				if(check_sum == temp_RxOneFrameBuffer[temp_RxOneFrame_BytesCn-2])
				{
					if(temp_RxOneFrameBuffer[2] == 0x00)
					{
						*u8_id = temp_RxOneFrameBuffer[4];
						*u8_sub_id = temp_RxOneFrameBuffer[5];
						if(temp_RxOneFrameBuffer[3] == 2)
						{ 
							*u8_length = 0;
						}
						else
						{
							return FALSE;
						}
						//*p_u8_txData =	//que ren zheng  mei you shu ju kuai
						return TRUE;
					}
					else
					{
						*u8_id = temp_RxOneFrameBuffer[2];
						*u8_sub_id = temp_RxOneFrameBuffer[4];
						if(temp_RxOneFrameBuffer[3] >= 2 && (temp_RxOneFrameBuffer[3] == (temp_RxOneFrameBuffer[5] + 2)))
						{ 
							*u8_length = temp_RxOneFrameBuffer[5];
							if(*u8_length > 16) return FALSE;
							if((*u8_length + 8) != temp_RxOneFrame_BytesCn) return FALSE;
						}
						else
						{
							return FALSE;
						}
						for(i=0;i<*u8_length;i++)
						{
							*(p_u8_txData+i) = temp_RxOneFrameBuffer[6+i];
						}
						return TRUE;
					}
				}
			}
			Temp_get_last = Temp_get;
			break;
	  	}
		if(temp_RxOneFrame_BytesCn >=30)//full
		{
		  temp_RxOneFrame_BytesCn = 0;
		  Receive_frame_permission_flag = FALSE;
		  return FALSE;
		}
		Temp_get_last = Temp_get;
	}
	return FALSE;
}


static void drv_sci1SaveFrame(UINT8 Temp)
{
	static UINT8 Temp_last = 0;
	static BOOL Receive_permission_flag = 0;
	static UINT8 temp_RxDataBuffer[30];
	static UINT8 temp_RxData_cn=0;
	UINT8 i;
	  if(Temp_last == 0xAA && (Temp == 0X75))
	  {
		temp_RxData_cn = 0;
		temp_RxDataBuffer[temp_RxData_cn] = 0xAA;
		temp_RxData_cn++;
		Receive_permission_flag = 1;
	  }
	  if(Receive_permission_flag)
	  {
		temp_RxDataBuffer[temp_RxData_cn] = Temp;
		temp_RxData_cn++;
	  }
	  if(Receive_permission_flag == TRUE && (Temp == 0xD5))
	  {
		Receive_permission_flag = FALSE;
		if((s_SCI1RxDataBuffer.u8_count + temp_RxData_cn) < SCI_BUFFER_SIZE)
		{
			for(i=0;i<temp_RxData_cn;i++)
			{
				 drv_sci1DataBuffer_push(temp_RxDataBuffer[i]);
			}
		}
		//fen xi s_SCI1RxDataBuffer bing qie  cun fang dao xiang ying wei zhi zhong。
	  }
	  if(temp_RxData_cn >=30)//full
	  {
		  temp_RxData_cn = 0;
		  Receive_permission_flag = FALSE;
	  }
	  Temp_last = Temp;
}



#pragma CODE_SEG NON_BANKED 
__interrupt void Comm_isr_SCI1(void)
{
  UINT8 Temp;
  static UINT8 Temp_last = 0;
  static BOOL Receive_permission_flag = 0;
	if(SCI1SR1_RDRF) 
	{
	  Temp = SCI1SR1;
	  Temp = SCI1DRL;
	  drv_sci1SaveFrame(Temp);
	  //sciDataBuffer_push(Temp, &s_SCI1RxDataBuffer);
	}
}
#pragma CODE_SEG DEFAULT 

/*****************************************************************************
** End File
*****************************************************************************/

